1   /*
2    * Copyright (C) 2008 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect.testing.features;
18  
19  import com.google.common.annotations.GwtCompatible;
20  import com.google.common.collect.testing.Helpers;
21  
22  import java.lang.annotation.Inherited;
23  import java.lang.annotation.Retention;
24  import java.lang.annotation.RetentionPolicy;
25  import java.util.Map;
26  import java.util.Set;
27  
28  /**
29   * Optional features of classes derived from {@code Map}.
30   *
31   * @author George van den Driessche
32   */
33  // Enum values use constructors with generic varargs.
34  @SuppressWarnings("unchecked")
35  @GwtCompatible
36  public enum MapFeature implements Feature<Map> {
37    /**
38     * The map does not throw {@code NullPointerException} on calls such as
39     * {@code containsKey(null)}, {@code get(null)},
40     * {@code keySet().contains(null)} or {@code remove(null)}.
41     */
42    ALLOWS_NULL_KEY_QUERIES,
43    ALLOWS_NULL_KEYS(ALLOWS_NULL_KEY_QUERIES),
44    /**
45     * The map does not throw {@code NullPointerException} on calls such as
46     * {@code containsValue(null)}, {@code values().contains(null)} or
47     * {@code values().remove(null)}.
48     */
49    ALLOWS_NULL_VALUE_QUERIES,
50    ALLOWS_NULL_VALUES(ALLOWS_NULL_VALUE_QUERIES),
51    /**
52     * The map does not throw {@code NullPointerException} on calls such as
53     * {@code entrySet().contains(null)} or {@code entrySet().remove(null)}
54     */
55    ALLOWS_NULL_ENTRY_QUERIES,
56    /**
57     * The map does not throw {@code NullPointerException} on any {@code null}
58     * queries.
59     *
60     * @see #ALLOWS_NULL_KEY_QUERIES
61     * @see #ALLOWS_NULL_VALUE_QUERIES
62     * @see #ALLOWS_NULL_ENTRY_QUERIES
63     */
64    ALLOWS_ANY_NULL_QUERIES(
65        ALLOWS_NULL_ENTRY_QUERIES,
66        ALLOWS_NULL_KEY_QUERIES,
67        ALLOWS_NULL_VALUE_QUERIES
68    ),
69    RESTRICTS_KEYS,
70    RESTRICTS_VALUES,
71    SUPPORTS_PUT,
72    SUPPORTS_REMOVE,
73    FAILS_FAST_ON_CONCURRENT_MODIFICATION,
74    /**
75     * Indicates that the constructor or factory method of a map, usually an
76     * immutable map, throws an {@link IllegalArgumentException} when presented
77     * with duplicate keys instead of discarding all but one.
78     */
79    REJECTS_DUPLICATES_AT_CREATION,
80  
81    GENERAL_PURPOSE(
82        SUPPORTS_PUT,
83        SUPPORTS_REMOVE
84    );
85  
86    private final Set<Feature<? super Map>> implied;
87  
88    MapFeature(Feature<? super Map> ... implied) {
89      this.implied = Helpers.copyToSet(implied);
90    }
91  
92    @Override
93    public Set<Feature<? super Map>> getImpliedFeatures() {
94      return implied;
95    }
96  
97    @Retention(RetentionPolicy.RUNTIME)
98    @Inherited
99    @TesterAnnotation
100   public @interface Require {
101     public abstract MapFeature[] value() default {};
102     public abstract MapFeature[] absent() default {};
103   }
104 }